package net.oschina.archx.spring.sequoiadb.manager;

import net.oschina.archx.spring.sequoiadb.SequoiaFactory;
import net.oschina.archx.spring.sequoiadb.SequoiaSession;
import net.oschina.archx.spring.sequoiadb.SequoiaTransactionManagement;
import net.oschina.archx.spring.sequoiadb.session.SequoiaSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

/**
 * 巨杉数据库事务管理器
 *
 * @author Archx
 */
public class SequoiaTransactionManager implements SequoiaTransactionManagement, InitializingBean {

    private static ThreadLocal<SequoiaSession> context = new ThreadLocal<SequoiaSession>();

    private final Logger log = LoggerFactory.getLogger(getClass());

    private SequoiaFactory sequoiaFactory;

    public SequoiaFactory getSequoiaFactory() {
        return sequoiaFactory;
    }

    public void setSequoiaFactory(SequoiaFactory sequoiaFactory) {
        this.sequoiaFactory = sequoiaFactory;
    }

    /**
     * 开启事务
     *
     * @throws InterruptedException
     */
    @Override
    public void begin() {
        SequoiaSession session = context.get();
        if (session == null) {
            session = new SequoiaSessionTemplate(sequoiaFactory);
            context.set(session);
        }
        session.beginTransaction();
        log.debug("开启事务!");
    }

    /**
     * 提交事务
     */
    @Override
    public void commit() {
        SequoiaSession session = context.get();
        if (session != null) {
            session.commit();
            log.debug("提交事务!");
            context.remove();
        }
    }

    /**
     * 回滚事务
     *
     * @param code    异常编号
     * @param message 异常信息
     */
    @Override
    public void rollback(int code, String message) {
        SequoiaSession session = context.get();
        if (session != null) {
            session.rollback();
            log.debug("事务回滚! 异常代码 - {}, 信息 - {}", code, message);
            context.remove();
        }

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(sequoiaFactory, "必须指定巨杉数据库工厂实体!");
    }
}
